// 监护仪数据/中央站数据转发
package tcplib

import (
	"errors"
	"fmt"
	"net"
	"sync"
	"time"
)

type TcpClient struct {
	host    string         // 主机地址
	port    int            // 主机端口
	session *TcpSession    // 会话
	handler SessionHandler // 回调
	wait    sync.WaitGroup // 等待
	quit    chan struct{}  // 退出
}

func TcpClientStart(host string, port int, handler SessionHandler) *TcpClient {
	fmt.Println("TcpClientStart:", host, port)
	client := TcpClient{
		host:    host,
		port:    port,
		handler: handler,
		quit:    make(chan struct{}),
	}
	client.wait.Add(1)
	go func() {
		defer client.wait.Done()
		client.service()
	}()
	return &client
}

// 返回会话
func (c *TcpClient) Session() *TcpSession {
	return c.session
}

// 写数据
func (c *TcpClient) Write(buf []byte) (n int, err error) {
	if c.session == nil {
		return 0, errors.New("no connection")
	}
	return c.session.Write(buf)
}

// 停止服务
func (c *TcpClient) Stop() {
	// 退出服务
	close(c.quit)
	if c.session != nil {
		// 关闭会话
		c.session.Stop()
	}
	// 等待服务退出
	c.wait.Wait()
}

// 服务
func (c *TcpClient) service() {
	// fmt.Println("# TcpClient Service")
	defer func() {
		// fmt.Println("# TcpClient Service exit")
	}()
	for {
		select {
		case <-c.quit:
			// 退出信号
			return
		default:
			addr := c.host + ":" + fmt.Sprint(c.port)
			conn, err := net.Dial("tcp", addr)
			if err != nil {
				break
			}
			// 连接成功，新建会话
			c.session = TcpSessionStart(conn, c.handler)
			if c.session == nil {
				break
			}
			// 等待会话完成
			c.session.Wait()
		}
		// 超时重新连接
		time.Sleep(time.Duration(time.Second * 3))
	}
}
